# -*- coding: utf-8 -*-
import datetime
import importlib
import logging
import os
import random
import time

from common.tools.filesize import FileSize
from common.tools.qinius import QNApi, QNInfo
from qixiaobao import settings
from qiniu import Auth, put_file, put_data

logger = logging.getLogger('wehelp')


class QiniuUpload(object):
    def __init__(self):
        self.QINIU_ACCESS_KEY = 'mcWDw9QdBnZS3utP2ZPYUF2Rr4bQ6_10O4rvg-Et'
        self.QINIU_SECRET_KEY = 'vsn_EDRt4pB4Fzo-aXMxYEHTvqHcgPOJ96iw3hpk'
        access_key = self.QINIU_ACCESS_KEY
        secret_key = self.QINIU_SECRET_KEY
        # 构建鉴权对象
        self.q = Auth(access_key, secret_key)
        if settings.DEBUG:
            self.expire = 600

    def upload_by_data(self, file, bucket_name='qixiaobao'):
        now_time = str(datetime.datetime.now().strftime('%Y%m%d%H%M%S'))
        key = now_time + '-' + file.name
        # 生成上传 Token，可以指定过期时间等
        token = self.q.upload_token(bucket_name, key, self.expire or 3600)
        # 要上传文件的本地路径
        ret, info = put_data(token, key, file.read())
        return ret


class UploadBase64ToQiNiu(object):
    """上传base64图片"""

    def upload_base64(self, data, bucket, key):
        # logger.debug(data[:22])
        if data[:22] == 'data:image/png;base64,':
            data = data[22:]
        supply = len(data) % 4
        if supply != 0:
            data += (4 - supply) * '='

        result = QNApi().putb64(data, bucket, key)
        if 'error' in result:
            return_info = {
                'status': 1,
                'detail': result['error']
            }
        else:
            return_info = {
                'status': 0,
                'detail': result['key']
            }
        return return_info


class UploadToQiNiu(object):
    """上传文件"""
    source_filter = {'picture': ['.png', '.jpg', '.jpeg', '.gif', '.bmp'],
                     'pdf': ['.pdf'],
                     'media': ['.mp3', '.wav', '.mp4', '.flv', '.mpeg', '.mpg']}

    def __init__(self, tinymce=False, *args, **kwargs):
        self.tinymce = tinymce
        super(UploadToQiNiu, self).__init__()

    def __get_path_format_vars(self):
        return {
            "year": datetime.datetime.now().strftime("%Y"),
            "month": datetime.datetime.now().strftime("%m"),
            "day": datetime.datetime.now().strftime("%d"),
            "time": datetime.datetime.now().strftime("%H%M%S"),
            "datetime": datetime.datetime.now().strftime("%Y%m%d%H%M%S"),
            "rnd": random.randrange(100, 999)
        }

    def __save_upload_file_to_qiniu(self, upload_file, bucket, key):
        """保存上传文件到七牛"""
        if not bucket:
            bucket = 'qixiaobao'
        try:
            from qiniu import Auth, put_file, put_data
            q = Auth(QNInfo.QINIU_ACCESS_KEY, QNInfo.QINIU_SECRET_KEY)
            token = q.upload_token(bucket, key)
            # ret,  info = put_file(token, key, upload_file)
            ret, info = put_data(token, key, upload_file)
            if not ret.get('key', None):
                raise Exception('upload error')
            else:
                return u"SUCCESS"
        except Exception as e:
            return str(e)

    def __get_output_path(self, path_format_var):
        # 取得输出文件的路径
        # OutputPathFormat = ("%(basename)s_%(datetime)s_%(rnd)s.%(extname)s" % path_format_var).replace("\\", "/")
        OutputPathFormat = ("%(datetime)s_%(rnd)s.%(extname)s" % path_format_var).replace("\\", "/")
        # 分解OutputPathFormat
        OutputPath, OutputFile = os.path.split(OutputPathFormat)
        OutputPath = os.path.join(settings.MEDIA_ROOT, OutputPath)
        if not os.path.exists(OutputPath):
            os.makedirs(OutputPath)
        return (OutputPathFormat, OutputPath, OutputFile)

    def upload_file(self, file, bucket, uid=None, filter_name='picture', save_type='local', file_size=''):
        if file is None:
            return {'status': 1, 'detail': 'no file'}
        if not bucket:
            bucket = 'qixiaobao'
        upload_file_name = file.name
        upload_file_size = file.size if not file_size else file_size

        # 取得上传的文件的原始名称
        upload_original_name, upload_original_ext = os.path.splitext(upload_file_name)
        upload_original_ext = upload_original_ext.lower()

        # 文件类型检验
        # if not upload_original_ext in self.source_filter[filter_name]:
        #    return {'status': 2, 'detail': "服务器不允许上传%s类型的文件。" % upload_original_ext}

        # 大小检验
        max_size = 2097152
        if filter_name == 'media':
            max_size = 209715200
        MF = FileSize(max_size)
        if upload_file_size > MF.size:
            return {'status': 3, 'detail': "上传文件大小不允许超过%s。" % MF.FriendValue}

        # 检测保存路径是否存在, 如果不存在则需要创建
        path_format_var = self.__get_path_format_vars()
        path_format_var.update({
            # "basename": base64.encodestring(upload_original_name).replace('\n', '').replace('/', '_'),
            "extname": upload_original_ext[1:],
            "filename": upload_file_name,
        })
        # 取得输出文件的路径
        OutputPathFormat, OutputPath, OutputFile = self.__get_output_path(path_format_var)

        if uid:
            OutputPathFormat = uid + '_' + OutputPathFormat
        # logger.debug(OutputPathFormat)

        # 所有检测完成后写入文件
        # 保存到文件中，如果保存错误，需要返回ERROR
        # 所有检测完成后写入文件
        # 保存到文件中，如果保存错误，需要返回ERROR
        if save_type == 'local':
            destination = open(settings.MEDIA_ROOT + '/' + OutputPathFormat, 'wb+')
            for chunk in file.chunks():
                destination.write(chunk)
            destination.close()
            state = u"SUCCESS"
            path = '%s%s' % (settings.MEDIA_URL, OutputPathFormat)
        else:
            state = self.__save_upload_file_to_qiniu(file, bucket, OutputPathFormat)
            path = QNApi().geturl(bucket, OutputPathFormat)
        # state = 'SUCCESS'

        if self.tinymce:
            return_info = {
                'status': 0,
                'detail': 'success',
                'error': False,
                'path': path,  # 完整的URL
                'name': OutputPathFormat,
            }
        else:
            # 返回数据
            return_info = {
                'status': 0,
                'detail': 'success',
                'name': OutputPathFormat,
                'path': path,
                'state': state,
            }
        return return_info

    def xcx_upload_file(self, file, bucket, uid=None, filter_name='picture', save_type='local'):

        if file is None:
            return {'status': 1, 'detail': 'no file'}
        if not bucket:
            bucket = 'qixiaobao'
        upload_file_name = filter_name

        # 取得上传的文件的原始名称
        upload_original_name, upload_original_ext = os.path.splitext(upload_file_name)
        upload_original_ext = upload_original_ext.lower()
        path_format_var = self.__get_path_format_vars()
        path_format_var.update({
            "extname": upload_original_ext[1:],
            "filename": upload_file_name,
        })
        # 取得输出文件的路径
        OutputPathFormat, OutputPath, OutputFile = self.__get_output_path(path_format_var)

        if uid:
            OutputPathFormat = uid + '_' + OutputPathFormat
        # logger.debug(OutputPathFormat)

        # 所有检测完成后写入文件
        # 保存到文件中，如果保存错误，需要返回ERROR
        # 所有检测完成后写入文件
        # 保存到文件中，如果保存错误，需要返回ERROR
        if save_type == 'local':
            destination = open(settings.MEDIA_ROOT + '/' + OutputPathFormat, 'wb+')
            for chunk in file.chunks():
                destination.write(chunk)
            destination.close()
            state = u"SUCCESS"
            path = '%s%s' % (settings.MEDIA_URL, OutputPathFormat)
        else:
            state = self.__save_upload_file_to_qiniu(file, bucket, OutputPathFormat)
            path = QNApi().geturl(bucket, OutputPathFormat)

        # state = 'SUCCESS'

        if self.tinymce:
            return_info = {
                'status': 0,
                'detail': 'success',
                'error': False,
                'path': path,  # 完整的URL
                'name': OutputPathFormat,
            }
        else:
            # 返回数据
            return_info = {
                'status': 0,
                'detail': 'success',
                'name': OutputPathFormat,
                'path': path,
                'state': state,
            }
        return return_info


def get_class(app_label, class_name):
    model_parent = importlib.import_module('%s.models' % app_label)
    model_class = getattr(model_parent, class_name)
    return model_class
